package com.baitiaojun.common.utils.ip;

import cn.hutool.core.net.URLDecoder;
import com.baitiaojun.common.utils.convert.CharsetConvertUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.lionsoul.ip2region.*;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

/**
 * ip 信息获取工具类
 */
@Slf4j
public class IpUtils {

    /**
     * 获取客户端ip地址
     * @param request
     * @return
     */
    public static String getIp(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.isEmpty() || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        //获取本地ip
        if (ip.equalsIgnoreCase("127.0.0.1") ||
                ip.equalsIgnoreCase("localhost") || ip.equalsIgnoreCase("0:0:0:0:0:0:0:1")) {
            try {
                return InetAddress.getLocalHost().getHostAddress();
            } catch (UnknownHostException e) {
                log.warn("ip获取异常");
                return StringUtils.EMPTY;
            }
        }
        //获取ip列表中的真实ip
        if (ip.indexOf(",") > 15) {
            ip = ip.substring(0, ip.indexOf(","));
        }
        return ip;
    }

    /**
     * 根据ip获取地址位置信息
     * @param ip
     * @return
     */
    public static String getAddressInfo(String ip) {
        if (!Util.isIpAddress(ip)) {
            log.warn("无效IP");
            return StringUtils.EMPTY;
        }
        URL resource = IpUtils.class.getResource("/ip2region.db");
        if (resource == null) {
            log.warn("无法获取ip2region资源");
            return StringUtils.EMPTY;
        }
        Charset charset = CharsetConvertUtils.convert(CharsetConvertUtils.UTF_8);
        Path path = Paths.get(URLDecoder.decode(resource.getPath(), charset));
        if (Files.notExists(path)) {
            log.warn("无法创建路径对象");
            return StringUtils.EMPTY;
        }
        String region;
        try {
            DbConfig dbConfig = new DbConfig();
            DbSearcher dbSearcher = new DbSearcher(dbConfig, path.toAbsolutePath().toString());
            DataBlock dataBlock = dbSearcher.btreeSearch(ip);
            region = dataBlock.getRegion();
        } catch (DbMakerConfigException | IOException e) {
            throw new RuntimeException(e);
        }
        return region;
    }

//    public static void main(String[] args) {
//        String addressInfo = getAddressInfo("192.168.21.7");
//        System.out.println(addressInfo);
//    }
}
